#pragma once
#include <iostream>
#include <cstring>
#include <sys/wait.h>
#include <pthread.h>
#include "Log.hpp"
#include "Common.hpp"
#include "ThreadPool.hpp"
using namespace ThreadPoolMoudule;
using namespace LogMoudule;
#define LOGBACK 8
class TcpServer
{
public:
    // using exec_t = std::function<std::string(std::string)>;
    struct Data
    {
        TcpServer *self;
        int sockfd;
    };
    TcpServer( int port) :  _port(port), _isrunning(false)
    {
    }
    void InitServer() // 初始化服务器
    {
        // 创建套接字
        _listensocket = ::socket(AF_INET, SOCK_STREAM, 0);
        if (_listensocket < 0)
        {
            LOG(LogLevel::FATAL) << "socket error!";
            Die(1);
        }
        LOG(LogLevel::INFO) << "socket success!";

        // bind
        struct sockaddr_in server;
        memset(&server, 0, sizeof(server));
        server.sin_family = AF_INET;
        server.sin_port = ::htons(_port);
        server.sin_addr.s_addr = INADDR_ANY;
        int n = ::bind(_listensocket, CONV(&server), sizeof(server));
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "bind error!";
            Die(2);
        }
        LOG(LogLevel::INFO) << "bind success!";

        // 3. cs,tcp是面向连接的，就要求tcp随时随地等待被连接
        // tcp 需要将socket设置成为监听状态
        n = ::listen(_listensocket, LOGBACK);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "listen error!";
            Die(3);
        }
        LOG(LogLevel::INFO) << "listen success!";
    }
    void HandleRequest(int sockfd) // 处理客户端请求
    {
        while (true)
        {
            char buffer[4096];
            int n = ::recv(sockfd, buffer, sizeof(buffer) - 1, 0);
            buffer[n] = 0;
            if (n > 0)
            {
                LOG(LogLevel::INFO) << "receive message from client:" << buffer;
                std::string sendmessage = "echo info:";
                sendmessage += buffer;
                // std::string sendmessage = _ex(buffer);
                ::send(sockfd, sendmessage.c_str(), sendmessage.size(), 0);
            }
            else if (n == 0)
            {
                LOG(LogLevel::INFO) << "client close the connection";
                break;
            }
            else
            {
                LOG(LogLevel::WARNING) << "read error!" << sockfd;
                break;
            }
        }
        ::close(sockfd);
    }
    static void *Handle(void *args)
    {
        Data *data = (Data *)args;
        data->self->HandleRequest(data->sockfd);
        delete data;
        return nullptr;
    }
    void Start()
    {
        _isrunning = true;
        while (_isrunning)
        {
            struct sockaddr_in peer;
            socklen_t peerlen = sizeof(peer);
            int _socket = ::accept(_listensocket, CONV(&peer), &peerlen);
            LOG(LogLevel::DEBUG) << "...accepting";

            if (_socket < 0)
            {
                LOG(LogLevel::WARNING) << "accept error!,socket is " << _socket;
                continue;
            }
            LOG(LogLevel::INFO) << "accept success!,socket is " << _socket;
            // version1--进程
            //  pid_t id = fork();
            //  if (id == 0)
            //  {
            //      ::close(_listensocket);
            //      if(fork()>0) exit(0);   //子进程创建进程，对于父进程来说就是孙子进程，子进程退出，孙子进程被shell进程领养，由shell进程回收
            //      HandleRequest(_socket);
            //      exit(0);
            //  }
            //  ::close(_socket);
            //  pid_t tid=waitpid(id,nullptr,0);
            //  if(tid<0)
            //  {
            //      LOG(LogLevel::WARNING)<<"waitpid error , child pid:"<<id;
            //  }

            // version2--线程
            //  Data* data=new Data();
            //  data->self=this;
            //  data->sockfd=_socket;
            //  pthread_t tid;
            //  int n=::pthread_create(&tid,nullptr,Handle,data);
            //  if(n!=0)
            //  {
            //      LOG(LogLevel::WARNING)<<"create pthread error";
            //  }

            // version3--线程池
            ThreadPool<std::function<void()>>::getInstance()->Equeue([this, _socket]()
                                                                     { this->HandleRequest(_socket); });
        }
    }
    void Stop()
    {
        _isrunning = false;
    }
    ~TcpServer()
    {
    }

private:
    int _listensocket; // 监听文件符
    bool _isrunning;
    int _port;
    // exec_t _ex;
};